<template>
    <div class="dagre-base_wrapper">
        <div class="dagre-header-wrap">
            <h3>dagre基本用法</h3>
            <p class="redirect-field">
                <span :class="[
                    'field-item',
                    { 'active': dirIndex === index }
                ]"  
                v-for="(item, index) in layoutRedirect" 
                :key="index" 
                @click="onSelectDir(item, index)">{{ item.name }}</span>
            </p>
        </div>
        <div class="dagre-map-gragh" id="container">
            
        </div>
    </div>
</template>

<script setup>
import dagre from "@dagrejs/dagre";
import { initDagreTree } from "./toolkit";

const dirIndex = ref(0)

// 创建图形容器
const graph = new dagre.graphlib.Graph({ directed: true, multigraph: true })

// 布局方向
const layoutRedirect = ref([
    { name: '从上到下布局', value: 'TB' },
    { name: '从下到上布局', value: 'BT' },
    { name: '从左到右布局', value: 'LR' },
    { name: '从右到左布局', value: 'RL' },
])

const nodeList = ref([
    {id: 'kspacey', node: { label: "Kevin Spacey",  width: 144, height: 100 } },
    {id: 'swilliams', node: { label: "Saul Williams", width: 160, height: 100 } },
    {id: 'bpitt', node: { label: "Brad Pitt",     width: 108, height: 100 } },
    {id: 'hford', node: { label: "Harrison Ford", width: 168, height: 100 } },
    {id: 'lwilson', node: { label: "Luke Wilson",   width: 144, height: 100 } },
    {id: 'kbacon', node: { label: "Kevin Bacon",   width: 121, height: 100 }}
])
const edgeList = ref([
    { sourceId: 'kspacey', targetId: 'swilliams' },
    { sourceId: 'swilliams', targetId: 'kbacon' },
    { sourceId: 'bpitt', targetId: 'kbacon' },
    { sourceId: 'hford', targetId: 'lwilson' },
    { sourceId: 'lwilson', targetId: 'kbacon' },
])
const coordinateNodes = ref([])
const coordinateEdges = ref([])

// 初始化树
const updateTree = (rankdirType="TB") => {
    coordinateNodes.value = []
    coordinateEdges.value = []
    const containerDom = document.querySelector(".dagre-map-gragh");
    const { clientWidth, clientHeight } = containerDom;
    
    // 配置图形setGraph对象设置属性
    graph.setGraph({
        rankdir: rankdirType,
        width: clientWidth,
        height: clientHeight,
        align: 'UR',
        nodesep: 50, // 同层节点间距
        edgesep: 10, // 布局中水平分隔边缘的像素数
        ranksep: 60, // 层级间距
        marginx: 10,  // x 轴方向的边距
        marginy: 10   // y 轴方向的边距
    })
    // 默认为每个新边分配一个新对象作为标签。
    graph.setDefaultEdgeLabel(function() { return {}})
    // 添加节点到图形容器，第一个参数是节点ID，
    // 第二个有关节点的元数据，此处为每个节点添加标签
    // 配置节点
    nodeList.value.forEach(el => graph.setNode(el.id, el.node))
    // 配置边
    edgeList.value.forEach(el => graph.setEdge(el.sourceId, el.targetId))

    // 让dagre为这些节点和边做布局
    // layout图形将使用布局信息进行更新，节点node获得节点中心坐标x和y
    // 边edge获取一个points属性，该属性包括边的控制点坐标以及边与节点相交处的点
    // 边edge中此弯曲中心的x坐标和y坐标
    dagre.layout(graph)
    
    graph.nodes().forEach(function(v) {
        coordinateNodes.value.push(graph.node(v))
        // console.log("Node " + v + ": " + JSON.stringify(graph.node(v)));
    });

    graph.edges().forEach(function(e) {
        coordinateEdges.value.push(graph.edge(e))
        // console.log("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e)));
    });

    // 打印节点和边数据
    console.log(coordinateNodes.value, coordinateEdges.value);

    // 创建paper容器，用于放置图形元素
    const paper = initDagreTree({ container: ".dagre-map-gragh", connector:'curve', nodes: coordinateNodes.value, links: coordinateEdges.value, model: graph })
}

nextTick(() => {
    updateTree()
})

// 切换方向
function onSelectDir(item, index) {
    dirIndex.value = index
    updateTree(item.value)
}

</script>
<style lang="scss" src="./style.scss"></style>
